//
//  CategoriesAndExtensionsTest.m
//  test_simple_project
//
//  分类和扩展语法特性测试实现
//

#import "CategoriesAndExtensionsTest.h"
#import <CommonCrypto/CommonDigest.h>

// 全局常量定义
NSString * const CategoryTestNotificationName = @"CategoryTestNotification";
NSString * const CategoryTestErrorDomain = @"CategoryTestErrorDomain";
NSInteger const CategoryTestDefaultValue = 100;

#pragma mark - 主类实现

@implementation CategoriesAndExtensionsTest

- (instancetype)init {
    self = [super init];
    if (self) {
        _baseProperty = @"Base Property Value";
        _baseValue = 42;
        
        // 初始化私有属性
        _privateDataArray = [[NSMutableArray alloc] init];
        _privateDataDictionary = [[NSMutableDictionary alloc] init];
        _privateFlag = NO;
        _privateQueue = dispatch_queue_create("com.test.private.queue", DISPATCH_QUEUE_SERIAL);
    }
    return self;
}

- (void)performBasicOperation {
    NSLog(@"执行基础操作: %@", self.baseProperty);
    [self performPrivateOperation];
}

- (NSString *)getBasicInfo {
    return [NSString stringWithFormat:@"基础信息 - 属性: %@, 值: %ld", 
            self.baseProperty, (long)self.baseValue];
}

#pragma mark - 私有方法实现

- (void)performPrivateOperation {
    self.privateFlag = YES;
    [self.privateDataArray addObject:@"私有操作数据"];
    NSLog(@"执行私有操作完成");
}

- (NSString *)generatePrivateIdentifier {
    return [NSString stringWithFormat:@"PRIVATE_%ld_%@", 
            (long)[[NSDate date] timeIntervalSince1970], 
            [[NSUUID UUID] UUIDString]];
}

- (void)processPrivateData:(NSArray *)data {
    [self.privateDataArray addObjectsFromArray:data];
    for (id item in data) {
        NSString *key = [NSString stringWithFormat:@"key_%@", item];
        self.privateDataDictionary[key] = item;
    }
}

- (BOOL)validatePrivateState {
    return self.privateFlag && self.privateDataArray.count > 0;
}

- (NSUInteger)privateDataCount {
    return self.privateDataArray.count;
}

- (NSString *)privateDataSummary {
    return [NSString stringWithFormat:@"私有数据摘要: %lu 项数据, 标志: %@", 
            (unsigned long)self.privateDataCount, 
            self.privateFlag ? @"是" : @"否"];
}

@end

#pragma mark - NSString分类实现

@implementation NSString (StringValidation)

- (BOOL)isValidEmail {
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}";
    NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailPredicate evaluateWithObject:self];
}

- (BOOL)isValidPhoneNumber {
    NSString *phoneRegex = @"^[0-9]{10,15}$";
    NSPredicate *phonePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex];
    return [phonePredicate evaluateWithObject:self];
}

- (BOOL)isValidURL {
    NSURL *url = [NSURL URLWithString:self];
    return url != nil && url.scheme != nil && url.host != nil;
}

- (BOOL)containsOnlyNumbers {
    NSCharacterSet *nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    return [self rangeOfCharacterFromSet:nonNumbers].location == NSNotFound;
}

- (BOOL)containsOnlyLetters {
    NSCharacterSet *nonLetters = [[NSCharacterSet letterCharacterSet] invertedSet];
    return [self rangeOfCharacterFromSet:nonLetters].location == NSNotFound;
}

- (NSString *)trimmedString {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)capitalizedFirstLetter {
    if (self.length == 0) return self;
    NSString *firstLetter = [[self substringToIndex:1] uppercaseString];
    NSString *remainingString = [self substringFromIndex:1];
    return [firstLetter stringByAppendingString:remainingString];
}

- (NSString *)reversedString {
    NSMutableString *reversed = [[NSMutableString alloc] init];
    for (NSInteger i = self.length - 1; i >= 0; i--) {
        [reversed appendString:[self substringWithRange:NSMakeRange(i, 1)]];
    }
    return [reversed copy];
}

- (NSArray<NSString *> *)wordsArray {
    return [self componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)md5Hash {
    const char *cStr = [self UTF8String];
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    CC_MD5(cStr, (CC_LONG)strlen(cStr), digest);
    
    NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [result appendFormat:@"%02x", digest[i]];
    }
    return result;
}

- (NSString *)base64EncodedString {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return [data base64EncodedStringWithOptions:0];
}

- (NSString *)urlEncodedString {
    return [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
}

@end

#pragma mark - NSArray分类实现

@implementation NSArray (ArrayUtilities)

- (NSArray *)shuffledArray {
    NSMutableArray *mutableArray = [self mutableCopy];
    NSUInteger count = mutableArray.count;
    for (NSUInteger i = 0; i < count; i++) {
        NSUInteger randomIndex = arc4random_uniform((uint32_t)(count - i)) + i;
        [mutableArray exchangeObjectAtIndex:i withObjectAtIndex:randomIndex];
    }
    return [mutableArray copy];
}

- (NSArray *)uniqueObjects {
    return [[NSOrderedSet orderedSetWithArray:self] array];
}

- (id)randomObject {
    if (self.count == 0) return nil;
    NSUInteger randomIndex = arc4random_uniform((uint32_t)self.count);
    return self[randomIndex];
}

- (NSArray *)arrayByRemovingObject:(id)object {
    NSMutableArray *mutableArray = [self mutableCopy];
    [mutableArray removeObject:object];
    return [mutableArray copy];
}

- (BOOL)containsObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
    return [self indexOfObjectPassingTest:predicate] != NSNotFound;
}

- (id)firstObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
    NSUInteger index = [self indexOfObjectPassingTest:predicate];
    return index != NSNotFound ? self[index] : nil;
}

- (NSArray *)objectsPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
    NSIndexSet *indexes = [self indexesOfObjectsPassingTest:predicate];
    return [self objectsAtIndexes:indexes];
}

- (NSUInteger)countOfObjectsPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
    return [[self indexesOfObjectsPassingTest:predicate] count];
}

@end

#pragma mark - UIView分类实现

#if TARGET_OS_IOS
@implementation UIView (FrameUtilities)

- (CGFloat)x {
    return self.frame.origin.x;
}

- (void)setX:(CGFloat)x {
    CGRect frame = self.frame;
    frame.origin.x = x;
    self.frame = frame;
}

- (CGFloat)y {
    return self.frame.origin.y;
}

- (void)setY:(CGFloat)y {
    CGRect frame = self.frame;
    frame.origin.y = y;
    self.frame = frame;
}

- (CGFloat)width {
    return self.frame.size.width;
}

- (void)setWidth:(CGFloat)width {
    CGRect frame = self.frame;
    frame.size.width = width;
    self.frame = frame;
}

- (CGFloat)height {
    return self.frame.size.height;
}

- (void)setHeight:(CGFloat)height {
    CGRect frame = self.frame;
    frame.size.height = height;
    self.frame = frame;
}

- (CGFloat)centerX {
    return self.center.x;
}

- (void)setCenterX:(CGFloat)centerX {
    CGPoint center = self.center;
    center.x = centerX;
    self.center = center;
}

- (CGFloat)centerY {
    return self.center.y;
}

- (void)setCenterY:(CGFloat)centerY {
    CGPoint center = self.center;
    center.y = centerY;
    self.center = center;
}

- (void)setFrameWithX:(CGFloat)x y:(CGFloat)y width:(CGFloat)width height:(CGFloat)height {
    self.frame = CGRectMake(x, y, width, height);
}

- (void)centerInSuperview {
    if (self.superview) {
        self.center = CGPointMake(self.superview.bounds.size.width / 2.0, 
                                 self.superview.bounds.size.height / 2.0);
    }
}

- (void)centerHorizontallyInSuperview {
    if (self.superview) {
        self.centerX = self.superview.bounds.size.width / 2.0;
    }
}

- (void)centerVerticallyInSuperview {
    if (self.superview) {
        self.centerY = self.superview.bounds.size.height / 2.0;
    }
}

- (void)removeAllSubviews {
    for (UIView *subview in self.subviews) {
        [subview removeFromSuperview];
    }
}

- (UIView *)findSubviewOfClass:(Class)viewClass {
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:viewClass]) {
            return subview;
        }
        UIView *found = [subview findSubviewOfClass:viewClass];
        if (found) {
            return found;
        }
    }
    return nil;
}

- (NSArray<UIView *> *)findAllSubviewsOfClass:(Class)viewClass {
    NSMutableArray *result = [[NSMutableArray alloc] init];
    for (UIView *subview in self.subviews) {
        if ([subview isKindOfClass:viewClass]) {
            [result addObject:subview];
        }
        [result addObjectsFromArray:[subview findAllSubviewsOfClass:viewClass]];
    }
    return [result copy];
}

@end
#endif

#pragma mark - 协议支持分类实现

@implementation CategoriesAndExtensionsTest (ProtocolSupport)

- (void)requiredCategoryMethod {
    NSLog(@"执行必需的分类协议方法");
}

- (NSString *)requiredCategoryMethodWithParameter:(id)parameter {
    return [NSString stringWithFormat:@"分类协议方法处理参数: %@", parameter];
}

- (void)optionalCategoryMethod {
    NSLog(@"执行可选的分类协议方法");
}

- (BOOL)optionalCategoryMethodReturningBool {
    return YES;
}

- (void)demonstrateProtocolSupport {
    [self requiredCategoryMethod];
    NSString *result = [self requiredCategoryMethodWithParameter:@"测试参数"];
    NSLog(@"协议支持演示: %@", result);

    if ([self respondsToSelector:@selector(optionalCategoryMethod)]) {
        [self optionalCategoryMethod];
    }
}

@end

#pragma mark - 数据处理分类实现

@implementation CategoriesAndExtensionsTest (DataProcessing)

- (void)processStringData:(NSArray<NSString *> *)strings {
    NSLog(@"处理字符串数据，共 %lu 项", (unsigned long)strings.count);
    for (NSString *string in strings) {
        NSString *processed = [string trimmedString];
        [self.privateDataArray addObject:processed];
    }
}

- (void)processNumberData:(NSArray<NSNumber *> *)numbers {
    NSLog(@"处理数字数据，共 %lu 项", (unsigned long)numbers.count);
    NSNumber *sum = @0;
    for (NSNumber *number in numbers) {
        sum = @([sum doubleValue] + [number doubleValue]);
    }
    self.privateDataDictionary[@"sum"] = sum;
}

- (NSDictionary *)analyzeData:(NSArray *)data {
    NSMutableDictionary *analysis = [[NSMutableDictionary alloc] init];

    analysis[@"total_count"] = @(data.count);
    analysis[@"string_count"] = @([data countOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [obj isKindOfClass:[NSString class]];
    }]);
    analysis[@"number_count"] = @([data countOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [obj isKindOfClass:[NSNumber class]];
    }]);

    return [analysis copy];
}

- (NSString *)generateDataReport {
    return [NSString stringWithFormat:@"数据报告 - 私有数组: %lu 项, 私有字典: %lu 项",
            (unsigned long)self.privateDataArray.count,
            (unsigned long)self.privateDataDictionary.count];
}

@end

#pragma mark - 网络操作分类实现

@implementation CategoriesAndExtensionsTest (NetworkOperations)

- (void)performNetworkRequest:(NSString *)urlString completion:(void(^)(NSData *data, NSError *error))completion {
    NSURL *url = [NSURL URLWithString:urlString];
    if (!url) {
        NSError *error = [NSError errorWithDomain:CategoryTestErrorDomain
                                             code:1001
                                         userInfo:@{NSLocalizedDescriptionKey: @"无效的URL"}];
        completion(nil, error);
        return;
    }

    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url
                                                             completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(data, error);
        });
    }];
    [task resume];
}

- (void)uploadData:(NSData *)data toURL:(NSString *)urlString completion:(void(^)(BOOL success, NSError *error))completion {
    NSURL *url = [NSURL URLWithString:urlString];
    if (!url) {
        NSError *error = [NSError errorWithDomain:CategoryTestErrorDomain
                                             code:1002
                                         userInfo:@{NSLocalizedDescriptionKey: @"无效的上传URL"}];
        completion(NO, error);
        return;
    }

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = data;

    NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request
                                                                               fromData:data
                                                                      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(error == nil, error);
        });
    }];
    [task resume];
}

- (void)downloadFileFromURL:(NSString *)urlString completion:(void(^)(NSString *filePath, NSError *error))completion {
    NSURL *url = [NSURL URLWithString:urlString];
    if (!url) {
        NSError *error = [NSError errorWithDomain:CategoryTestErrorDomain
                                             code:1003
                                         userInfo:@{NSLocalizedDescriptionKey: @"无效的下载URL"}];
        completion(nil, error);
        return;
    }

    NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithURL:url
                                                                      completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
        if (error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(nil, error);
            });
            return;
        }

        // 移动文件到文档目录
        NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
        NSString *fileName = response.suggestedFilename ?: @"downloaded_file";
        NSString *filePath = [documentsPath stringByAppendingPathComponent:fileName];

        NSError *moveError;
        [[NSFileManager defaultManager] moveItemAtURL:location toURL:[NSURL fileURLWithPath:filePath] error:&moveError];

        dispatch_async(dispatch_get_main_queue(), ^{
            completion(moveError ? nil : filePath, moveError);
        });
    }];
    [task resume];
}

@end

#pragma mark - 全局函数实现

NSString *CategoryTestGlobalFunction(NSString *input) {
    return [NSString stringWithFormat:@"全局函数处理: %@", input];
}

BOOL CategoryTestValidateInput(id input) {
    return input != nil && ![input isEqual:[NSNull null]];
}

NSArray *CategoryTestProcessArray(NSArray *input) {
    if (!input) return @[];

    NSMutableArray *processed = [[NSMutableArray alloc] init];
    for (id item in input) {
        if (CategoryTestValidateInput(item)) {
            [processed addObject:item];
        }
    }
    return [processed copy];
}
